﻿namespace _09_Tetris
{
    internal class Shape
    {

        public enum Direction { Up,Right,Down,Left}

        protected Direction dir;

        protected Block[] blocks;
        protected Pos pos;
        protected ConsoleColor color;

        Map map;

        public Shape(ref Map map)
        {
            this.map = map;
            blocks = new Block[4];
            for (int i = 0;i < 4;i++)
            {
                blocks[i] = new Block();
            }
            pos.x = 5;
            pos.y = 1;
            dir  = Direction.Up;
        }

        // 面向对象 多态
        // virtual 虚函数
        // 基类的方法如果是virtual的
        // 在调用的时候就会去找子类是否有override的方法
        // 可以在子类通过base关键字调用基类的方法
        public virtual void Update()
        {

        }

        public void Render()
        {
            for (int i = 0; i < 4; i++)
            {
                Console.ForegroundColor = color;
                Console.SetCursorPosition(blocks[i].pos.x * 2, blocks[i].pos.y);
                Console.Write("■");
                Console.ResetColor();
            }
        }

        public void Clear()
        {
            for (int i = 0; i < 4; i++)
            {
                Console.SetCursorPosition(blocks[i].pos.x * 2, blocks[i].pos.y);
                Console.Write("  ");
            }
        }

        public void Move(int dir)
        {
            Clear();
            pos.x += dir;
        }

        public void Drop(bool isClear = true)
        {
            if (isClear)
            {
                Clear();
            }
            pos.y++;
        }

        public void Rotate(bool clockwise = true)
        {
            Clear();
            if (clockwise)
            {
                dir++;
                if(dir > Direction.Left)
                {
                    dir = Direction.Up;
                }
            }
            else
            {
                dir--;
                if (dir < Direction.Up)
                {
                    dir = Direction.Left;
                }
            }
        }

        public bool CheckHit(Map.Type type, int offsetX,int offsetY)
        {
            for (int i = 0; i < blocks.Length; i++)
            {
                // 如果地图上block所在格的类型是墙
                if (map.GetType(blocks[i].pos,offsetX,offsetY) == type)
                {
                    return true;
                }
            }
            return false;
        }

        public void Solidify()
        {
            for (int i = 0; i < blocks.Length; i++)
            {
                map.ChangeType(blocks[i].pos, Map.Type.Wall);
            }
        }

        // 面向对象 继承
        // 已有的类 基类（父类）
        // 继承已有的类的类 派生类（子类）
        // <访问修饰符> class <基类>
        // {
        //      ...
        // }
        // <访问修饰符> class <派生类> ： <基类>
        // {
        //      ...
        // } 
        // 作用
        // 1.代码复用
        // 除了构造函数 析构函数等特殊函数不继承 其他都继承
        // 构造子类时会先调用父类的构造函数 再调用自己的构造函数
        // 成员属性也是一样 先构造成员属性 构造完再构造自己
        // C#不允许多继承 原因就是成员属性可能有二义性
        // 想要多继承 可以使用接口 Interface

        public void SaveColor()
        {
            color = ConsoleColor.Gray;
        }

        public void SetPos(int x,int y)
        {
            pos.x = x; 
            pos.y = y;
            Update();
        }

        public void SetDir(Direction dir)
        {
            this.dir = dir;
        }

        public Direction GetDir()
        {
            return dir;
        }

        public int GetPosX()
        {
            return pos.x;
        }

        public void DropBottom()
        {
            while (!CheckHit(Map.Type.Wall, 0, 1))
            {
                Drop(false);
                Update();
            }
        }
    }
}
